/*******************************************
  Jose Andres Lara Vecino

  Author       : $$Author: cainlara@gmail.com $$
  Last CheckIn : $$Date: 2012-10-29 19:04:52 +0000 (Mon, 29 Oct 2012) $$
  Revision     : $$Revision: 108 $$
*******************************************/

package utilidad;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

import control.IPropiedadesSistema;
import core.ManejadorLog;
import core.PropiedadSistema;
import frente.UsuarioGuardado;

/**
 * Repositorio de metodos.
 * <P>
 * Esta clase es usada como repositorio 
 * de funcionalidades que deben estar 
 * disponibles para toda la ejecución de 
 * la aplicacion.
 * 
 * @author jose.lara 07.06.2012
 */
public final class Util {
    public static final String NOMBRE_CARPETA                   = "TmMangerConf";
    public static final String SEPARADOR_ARCHIVO                = System.getProperties().getProperty("file.separator");
    public static final String INICIO_USUARIO                   = System.getProperties().getProperty("user.home");
    
    private static List<PropiedadSistema> propiedadesSistema    = null;
    
    private Util() {
        //Imposible instanciar
    }
    
    /**
     * Obtiene las dimensiones de la pantalla.
     * <P>
     * Analiza las dimensiones de la pantalla 
     * y retorna un objeto <code>Dimension</code>.
     * 
     * @return un objeto <code>Dimension</code> 
     * que especifica el tamaño de la pantalla del 
     * equipo que ejecuta el aplicativo.
     */
    public static Dimension obtenerTamanoPantalla() {
        Dimension pantalla  = null;
        Toolkit tk          = null;
        
        tk = Toolkit.getDefaultToolkit();
        pantalla = tk.getScreenSize();
        
        return pantalla;
    }
    
    public static boolean cadenaValida(String cadena) {
        return cadena != null && cadena.trim().length() > 0;
    }
    
    public static boolean cadenaValida(char [] cadena) {
        return cadena != null && cadenaValida(String.valueOf(cadena));
    }
    
    public static boolean cadenasValidas(String ... cadenas) {
        for(String cadena : cadenas) {
            if(!cadenaValida(cadena)) {
                return false;
            }
        }
        
        return true;
    }
    
    public static boolean cadenasValidas(int longitud, String ... cadenas) {
        for(String cadena : cadenas) {
            if(!cadenaValida(cadena) || cadena.length() > longitud) {
                return false;
            }
        }
        
        return true;
    }
    
    @SuppressWarnings("rawtypes")
    public static boolean listaValida(List lista) {
        return lista != null && !lista.isEmpty();
    }
    
    public static File obtenerArchivo(String nombreArchivo) {
        File archivo        = null;
        String pathArchivo  = null;
        boolean continuar   = true;
        
        if(!existeCarpetaConfiguracion()) {
            continuar = crearCarpetaConfiguracion();
        }
        
        if(continuar) {
            pathArchivo = getRutaCarpetaConfiguracion() + SEPARADOR_ARCHIVO + nombreArchivo;
            
            archivo = new File(pathArchivo);
        }
        
        return archivo;
    }
    
    public static boolean existeCarpetaConfiguracion() {
        return (new File(getRutaCarpetaConfiguracion())).exists();
    }
    
    public static String getRutaCarpetaConfiguracion() {
        return INICIO_USUARIO + SEPARADOR_ARCHIVO + NOMBRE_CARPETA;
    }
    
    public static boolean crearCarpetaConfiguracion() {
        File carpeta = null;
        
        carpeta = new File(getRutaCarpetaConfiguracion());
        
        return carpeta.mkdir();
    }
    
    public static boolean existeArchivoConfiguracion() {
        File archivo    = null;
        
        archivo = obtenerArchivo(IPropiedadesSistema.ARCHIVO_CONFIG);
        
        if(archivo != null) {
            return archivo.exists();
        }
        
        return false;
    }
    
    public static UsuarioGuardado obtenerUsuarioGuardado() throws IOException {
        UsuarioGuardado usuario     = null;
        File archivoConfiguracion   = null;
        FileReader lector           = null;
        BufferedReader buffer       = null;
        String linea                = null;
        String nombreUsuario        = null;
        String clave                = null;
        
        if(existeArchivoConfiguracion()) {
            archivoConfiguracion = obtenerArchivo(IPropiedadesSistema.ARCHIVO_CONFIG);
            try {
                if(archivoConfiguracion != null) {
                    lector = new FileReader(archivoConfiguracion);
                    
                    buffer = new BufferedReader(lector);
                    
                    linea = buffer.readLine();
                    
                    while(linea != null) {
                        if(linea.startsWith(IPropiedadesSistema.USUARIO)) {
                            nombreUsuario = linea.split(":")[1];
                        }
                        else if(linea.startsWith(IPropiedadesSistema.MARCA)) {
                            clave = linea.split(":")[1];
                        }
                        
                        linea = buffer.readLine();
                    }
                    
                    usuario = new UsuarioGuardado(nombreUsuario, clave);
                }
            }
            finally {
                cerrarStreams(lector, buffer);
            }
        }
        
        return usuario;
    }
    
    private static void cerrarStreams(FileReader lector, BufferedReader buffer) throws IOException {
        if(buffer != null) {
            buffer.close();
        }
        
        if(lector != null) {
            lector.close();
        }
    }
    
    public static String getMD5(String texto) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        return hex(md.digest(texto.getBytes("CP1252")));
    }
    
    private static String hex(byte[] array) {
        StringBuilder sb = new StringBuilder();
        
        for (int i = 0; i < array.length; ++i) {
            sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
        }
        
        return sb.toString();
    }
    
    private static List<PropiedadSistema> getPropiedadesSistema() {
        if(propiedadesSistema == null) {
            try {
                cargarPropiedadesSistema();
            }
            catch (IOException e) {
                ManejadorLog.escribirErrorEnLog(e);
            }
        }
        
        return propiedadesSistema;
    }
    
    private static void cargarPropiedadesSistema() throws IOException {
        File archivoConfig          = null;
        FileReader lector           = null;
        BufferedReader buffer       = null;
        PropiedadSistema propiedad  = null;
        String linea                = null;
        
        try {
            archivoConfig = obtenerArchivo(IPropiedadesSistema.ARCHIVO_CONFIG);
            
            if(archivoConfig != null && archivoConfig.exists()) {
                propiedadesSistema = new ArrayList<PropiedadSistema>();
                
                lector = new FileReader(archivoConfig);
                buffer = new BufferedReader(lector);
                
                linea = buffer.readLine();
                
                while (linea != null) {
                    if(linea.indexOf(':') > 0) {
                        propiedad = new PropiedadSistema(linea.split(":")[0], linea.split(":")[1]);
                        
                        propiedadesSistema.add(propiedad);
                    }
                    
                    linea = buffer.readLine();
                }
            }
        }
        finally {
            cerrarStreams(lector, buffer);
        }
    }
    
    public static void actualizarValorPropiedadSistema(String nombre, String valor) {
        PropiedadSistema propiedad = null;
        
        propiedad = getPropiedadSistema(nombre);
        
        if(propiedad == null) {
            propiedad = new PropiedadSistema(nombre, valor);
            getPropiedadesSistema().add(propiedad);
        }
        else {
            propiedad.setValor(valor);
        }
    }
    
    public static void guardarPropiedadesSistema() throws FileNotFoundException {
        FileNotFoundException lanzada   = null;
        File archivoConfiguracion       = null;
        PrintWriter impresor            = null;
        
        if(getPropiedadesSistema() != null && !getPropiedadesSistema().isEmpty()) {
            try {
                archivoConfiguracion = obtenerArchivo(IPropiedadesSistema.ARCHIVO_CONFIG);
                impresor = new PrintWriter(archivoConfiguracion);
                
                for(PropiedadSistema propiedad : getPropiedadesSistema()) {
                    impresor.println(propiedad.toString());
                }
            }
            catch(FileNotFoundException e) {
                lanzada = e;
            }
            finally {
                if(impresor != null) {
                    impresor.close();
                }
                
                if(lanzada != null) {
                    throw lanzada;
                }
            }
        }
    }
    
    private static PropiedadSistema getPropiedadSistema(String nombre) {
        List<PropiedadSistema> todas = null;
        
        todas = getPropiedadesSistema();
        
        if(todas != null) {
            for(PropiedadSistema propiedad : todas) {
                if(propiedad.getNombre().equals(nombre)) {
                    return propiedad;
                }
            }
        }
        
        return null;
    }
    
    public static String getValorPropiedadSistema(String nombre) {
        return getPropiedadSistema(nombre) != null ? getPropiedadSistema(nombre).getValor() : null;
    }
}